#ifndef _aky_flash_t_H
#define _aky_flash_t_H
#include "aky_program/aky_func.h"
#include "aky_program/aky_define.h"

#define AKY_ONE_SEC_SIZE (4096ul) //一个扇区大小
#define FLASH_BUF_SIZE (AKY_ONE_SEC_SIZE * 2) //flash缓存数组的大小

#define MAX_MEM_SIZE (30ul) //最大记忆组数
#define MAX_MEM_ADDR_SIZE ((uint32_t)4096)//
//----------------------------------------------------------------
#define AKY_FLASH_DEBUG_ENABLE (1) //(1)切换到内部flash (0)外部spi flash

//----------------------------------------------------------------
#define general_save_addr (flash_end_addr)//小数据通用保存地址 一个扇区大小


//主flash
#if (AKY_FLASH_DEBUG_ENABLE == 1)
//debug用内部flash
#define aky_flash_start_addr (0x7A000ul)//1024 * 488
#define user_set_addr (user_all_back_addr - (AKY_ONE_SEC_SIZE * 2))//设定保存
#define user_set_back_addr (user_set_addr + AKY_ONE_SEC_SIZE) //后备

#define user_all_back_addr (user_1_addr - (MAX_MEM_ADDR_SIZE))//所有用户共用的备份地址
#define user_1_addr (user_2_addr - (MAX_MEM_ADDR_SIZE))//用户1的保存地址
#define user_2_addr (user_3_addr - (MAX_MEM_ADDR_SIZE))//用户2的保存地址
#define user_3_addr (flash_end_addr - (MAX_MEM_ADDR_SIZE))//用户3的保存地址 预留
#define flash_end_addr (0x80000ul)//1024 * 512

#else
//正常用外部flash w25q128  后面0.2m   256k  
#define aky_flash_start_addr (flash_end_addr - (256 * 1024))//15.8m

#define user_set_addr (general_save_addr - (AKY_ONE_SEC_SIZE * 2))//设定保存
#define user_set_back_addr (user_set_addr + AKY_ONE_SEC_SIZE) //后备

#define general_save_addr (user_all_back_addr - (AKY_ONE_SEC_SIZE))//小数据通用保存地址 一个扇区大小
#define user_all_back_addr (user_1_addr - (MAX_MEM_ADDR_SIZE))//所有用户共用的备份地址
#define user_1_addr (user_2_addr - (MAX_MEM_ADDR_SIZE))//用户1的保存地址
#define user_2_addr (user_3_addr - (MAX_MEM_ADDR_SIZE))//用户2的保存地址
#define user_3_addr (flash_end_addr - (MAX_MEM_ADDR_SIZE))//用户地址

// #define flash_end_addr (0x1000000ul)//(1024 * 16) * 1024
#define flash_end_addr (0xf00000ul)//(1024 * 15) * 1024
#endif

//主flash
//----------------------------------------------------------------

#define SET_DATA_MAX_SAVE_CNT (16ul)//设定值多次保存  保存和检查次数  最大16次

//----------------------------------------------------------------
//小数据通用保存地址 一个扇区大小
//基于 general_save_addr 地址进行偏移
//操作时要调用专门的函数 
//flash_save_general_data()
// flash_get_general_data()

#define general_save_offset (10ul)// 每次读取的偏移字节大小 

#define life_test_addr (0 * general_save_offset)//相对于通用地址的偏移量 

typedef struct
{
    uint8_t buf[general_save_offset - 1];
    uint8_t check_sum;
}s_general_save_t; //通用保存结构体

typedef enum{
    AKY_FLASH_OK = 0,
    AKY_FLASH_ERR,
}e_aky_flash_t;

typedef enum
{
    MAIN_ADDR = 0, //
    BACK_ADDR,     //
} e_addr_t;        //

typedef struct 
{
    uint16_t cur_mem_index;//记录当前最新一笔记忆的下标位置
    uint16_t mem_set;//最大存储记忆笔数
    uint8_t flag_mem_overwrite : 1;//记忆溢出
    e_user_t e_user;
    uint8_t user_name_buf[100];
    e_gender_t gender;
    uint8_t age_buf[10];
    uint8_t phone_num_buf[30];
    uint8_t flag_is_user_info_valid;

    uint8_t check_sum;
}s_mem_index_t;//记忆下标 





extern s_mem_index_t g_s_mem_index;
extern e_aky_flash_t g_e_flash_err;
extern s_mem_t g_s_mem;
extern s_mem_t g_s_mem_send;
extern s_set_t g_s_set;
extern s_general_save_t g_s_general_save;


extern uint8_t *flash_buf; //
extern e_user_t g_e_user;

e_aky_flash_t aky_flash_write_bytes(uint32_t addr, uint8_t *p_u8_buf, uint16_t num);
e_aky_flash_t aky_flash_read_bytes(uint32_t addr, uint8_t *p_u8_buf, uint16_t num);
e_aky_flash_t aky_flash_erase_pages(uint32_t addr, uint16_t pages);
uint8_t get_bytes_checksum(uint8_t *p_u8_buf, uint16_t num);
uint16_t get_stru_checksum_offset_bytes(uint8_t *p_start_addr, uint8_t *p_stop_addr);
e_aky_flash_t flash_save_mem_index_data(s_mem_index_t s_mem_index, e_user_t e_user ,e_addr_t e_addr);
s_mem_index_t flash_get_mem_index_data(e_user_t e_user, e_aky_flash_t *p_e_flash_err,e_addr_t e_addr);
e_aky_flash_t flash_save_mem_data(s_mem_t s_mem, e_user_t e_user, uint16_t index,e_addr_t e_addr);
s_mem_t flash_get_mem_data(e_user_t e_user, uint16_t index, e_aky_flash_t *p_e_flash_err,e_addr_t e_addr);

void clr_mem_bank(e_user_t e_user);
e_aky_flash_t check_mem_checksum(e_user_t e_user,e_addr_t e_addr);
e_aky_flash_t mem_data_main_back_switch(uint32_t original_addr, uint32_t target_addr);
e_aky_flash_t check_mem_bank(e_user_t e_user);
e_aky_flash_t insert_one_mem(s_mem_t s_mem, e_user_t e_user);
void flash_test(void);
void store_set_to_flash(s_set_t s_set);
s_set_t get_flash_set_data(void);
e_aky_flash_t flash_save_general_data(uint16_t off_set, s_general_save_t s_general_save);
s_general_save_t flash_get_general_data(uint16_t off_set);
void clr_mem_bank_complete(e_user_t e_user);

void aky_flash_index_check(e_user_t e_user);
void clr_4G_mid_data(void);
void aky_flash_index_check(e_user_t e_user);
void write_full_mem_bank(e_user_t e_user);
void notice_one_test_complete(void);
void aky_flash_init(void);
void flash_test_2(void);
uint32_t get_user_addr(e_user_t e_user);
s_mem_index_t get_default_mem_index_data(void);

#endif // 